#include <SDL2/SDL.h>
#include "../paint.hpp"
#include "../window.hpp"
#include "../image.hpp"
// #include <iostream>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <chrono>
extern SDL_Surface* winSurface;
extern SDL_Window* window;

class GVECTOR {
	
	PIMAGE Pic;
	double *vector;
	color_t *GMap;
	int W, H, W21, H21, picH, picW;
	double GaussianWeight (int x, int y, double sigama = 1.5) {
		double sigama22 = 2 * sigama * sigama;
		return 1.0/(3.141592653 * sigama22) * pow(2.718281828, -(x*x + y*y) / sigama22);
	}
public:
	GVECTOR (PIMAGE pic, int w, int h = 0) {
		Pic = pic;
		picH = getheight (pic);
		picW = getwidth (pic);
		GMap = new color_t [picW * picH];
		for (int i = 0; i < picH; i ++) {
			for (int j = 0; j < picW; j ++) {
				GMap [i * picW + j] = (*pic).getC (j, i);
			}
		}

		if (h == 0) { H = w; }
		else        { H = h; }
		W = w;
		W21 = W * 2 + 1;
		H21 = H * 2 + 1;
		vector = new double [W21 * H21];

		for (int i = -H; i <= H; i ++) {
			for (int j = -W; j <= W; j ++) {
				vector [(i+H) * W21 + j + W] = GaussianWeight (i, j); 
			}
		}
	}
	PIMAGE getimage (void) {
		return Pic;
	}
	double GetColor (int i, int j) {
		if (i < 0 || i > H21 || j < 0 || j > W21) {
			return -1.0;
		} else {
			return vector [i*W21 + j];
		}
	}
	color_t GetMapColor (int i, int j) {
		if (i < 0 || i > picH || j < 0 || j > picW) {
			return 0x7f7f7fff;
		} else {
			return GMap [i * picW + j];
		}
	}
	color_t GetBlurColor (int x, int y) {
		double R = 0, G = 0, B = 0;
		color_t color;
		double num;
		for (int i = 0; i < H21; i ++) {
			for (int j = 0; j < W21; j ++) {
				color = GetMapColor (x - H + i, y - W + j);
				num = GetColor (i, j);
				R += XEGEGET_R(color) * num;
				G += XEGEGET_G(color) * num;
				B += XEGEGET_B(color) * num;
			}
		}
		return XEGERGB ((int)R, (int)G, (int)B);
	}
	void Blur (void) {
		for (int i = 0; i < picH; i ++) {
			for (int j = 0; j < picW; j ++) {
				putPixel (j, i, GetBlurColor (i, j), Pic);
			}
		}
	}
};